//**** Frame FAS search and check module ***//

module FRM_DSCRM(
   RESET,
   RCLK_155M,
   MPI_DSCRM_EN,

   FAS_LOF,
   FAS_OOF,
   FAS_FCNT8,
   FAS_FCNT270,
   FAS_FCNT9,
   FAS_DATA,

   DSCRM_LOF,
   DSCRM_OOF,
   DSCRM_FCNT8,
   DSCRM_FCNT270,
   DSCRM_FCNT9,
   DSCRM_DATA,
   MPI_PER_B1COUNT,
   MPI_PER_B1PULSE
   );

input              RESET;
input              RCLK_155M;
input              MPI_DSCRM_EN;

input              FAS_LOF;
input              FAS_OOF;
input[2:0]         FAS_FCNT8;
input[8:0]         FAS_FCNT270;
input[3:0]         FAS_FCNT9;
input[63:0]        FAS_DATA;

output reg         DSCRM_LOF;
output reg         DSCRM_OOF;
output reg[2:0]    DSCRM_FCNT8;
output reg[8:0]    DSCRM_FCNT270;
output reg[3:0]    DSCRM_FCNT9;
output reg[63:0]   DSCRM_DATA;
output reg[3:0]    MPI_PER_B1COUNT;
output reg         MPI_PER_B1PULSE;

reg                DSCRM_ADDR_EN;
reg[6:0]           DSCRM_ADDR_CNT;
wire[63:0]         DSCRM_VRCTOR;

reg[7:0]           B1_CALC_VALUE;
reg[7:0]           B1_FIANL_VALUE;
reg[7:0]           B1_FIANL_VALUE_ME1;
wire[7:0]          B1_XOR_VALUE;
reg[3:0]           B1_ERROR_CNT;


always @( FAS_FCNT9 or FAS_FCNT270 or FAS_FCNT8) begin
   if ( FAS_FCNT9[3:0]==4'd0 && FAS_FCNT270[8:0]<9'd8 )
         DSCRM_ADDR_EN               <= 1'b0;
   else if ( FAS_FCNT9[3:0]==4'd0 && FAS_FCNT270[8:0]==9'd8 ) begin
      if ( FAS_FCNT8[2:0]==3'd6 || FAS_FCNT8[2:0]==3'd7 )
         DSCRM_ADDR_EN               <= 1'b1;
      else
         DSCRM_ADDR_EN               <= 1'b0;
   end
   else if ( FAS_FCNT9[3:0]==4'd8 && FAS_FCNT270[8:0]==9'd269 ) begin
      if ( FAS_FCNT8[2:0]==3'd6 || FAS_FCNT8[2:0]==3'd7 )
         DSCRM_ADDR_EN               <= 1'b0;
      else
         DSCRM_ADDR_EN               <= 1'b1;
   end
   else begin
         DSCRM_ADDR_EN               <= 1'b1;
   end
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      DSCRM_ADDR_CNT[6:0]            <=7'd0;
   else begin
      if ( DSCRM_ADDR_EN==1'b0 )
          DSCRM_ADDR_CNT[6:0]        <=7'd0;
      else if ( DSCRM_ADDR_CNT[6:0]==7'd126 )
          DSCRM_ADDR_CNT[6:0]        <=7'd0;
      else
          DSCRM_ADDR_CNT[6:0]        <=DSCRM_ADDR_CNT[6:0] +7'd1;
   end
end

XLNX_SCRM_ROM   INST_DSCRM_TABLE(
   .clka        ( RCLK_155M ),
   .addra       ( DSCRM_ADDR_CNT[6:0] ),
   .douta       ( DSCRM_VRCTOR[63:0] )
   );

always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 ) begin
      DSCRM_LOF                   <= 1'b0;
      DSCRM_OOF                   <= 1'b0;
      DSCRM_FCNT8[2:0]            <= 3'd0;
      DSCRM_FCNT270[8:0]          <= 9'd0;
      DSCRM_FCNT9[3:0]            <= 4'd0;
   end
   else begin
      DSCRM_LOF                   <= FAS_LOF;
      DSCRM_OOF                   <= FAS_OOF;
      DSCRM_FCNT8[2:0]            <= FAS_FCNT8[2:0];
      DSCRM_FCNT270[8:0]          <= FAS_FCNT270[8:0];
      DSCRM_FCNT9[3:0]            <= FAS_FCNT9[3:0];
   end
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      DSCRM_DATA[63:0]            <= 64'd0;
   else begin
      if ( MPI_DSCRM_EN==1'b1 )  begin
         if ( FAS_FCNT9[3:0]==4'd0 && FAS_FCNT270[8:0]<9'd9 )
            DSCRM_DATA[63:0]      <= FAS_DATA[63:0];
         else
            DSCRM_DATA[63:0]      <= FAS_DATA[63:0] ^ DSCRM_VRCTOR[63:0];
      end
      else
         DSCRM_DATA[63:0]         <= FAS_DATA[63:0];
   end
end


//******** Section 3:  B1 errors check and B1 check  ********//
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      B1_CALC_VALUE[7:0]         <= 8'd0;
   else begin
      if ( FAS_FCNT9[3:0]==4'd0 && FAS_FCNT270[8:0]==9'd0 &&  FAS_FCNT8[2:0]==3'd0 ) begin
         B1_CALC_VALUE[7]        <= FAS_DATA[7] ^ FAS_DATA[15] ^ FAS_DATA[23] ^ FAS_DATA[31] ^ FAS_DATA[39] ^ FAS_DATA[47] ^ FAS_DATA[55] ^ FAS_DATA[63];
         B1_CALC_VALUE[6]        <= FAS_DATA[6] ^ FAS_DATA[14] ^ FAS_DATA[22] ^ FAS_DATA[30] ^ FAS_DATA[38] ^ FAS_DATA[46] ^ FAS_DATA[54] ^ FAS_DATA[62];
         B1_CALC_VALUE[5]        <= FAS_DATA[5] ^ FAS_DATA[13] ^ FAS_DATA[21] ^ FAS_DATA[29] ^ FAS_DATA[37] ^ FAS_DATA[45] ^ FAS_DATA[53] ^ FAS_DATA[61];
         B1_CALC_VALUE[4]        <= FAS_DATA[4] ^ FAS_DATA[12] ^ FAS_DATA[20] ^ FAS_DATA[28] ^ FAS_DATA[36] ^ FAS_DATA[44] ^ FAS_DATA[52] ^ FAS_DATA[60];
         B1_CALC_VALUE[3]        <= FAS_DATA[3] ^ FAS_DATA[11] ^ FAS_DATA[19] ^ FAS_DATA[27] ^ FAS_DATA[35] ^ FAS_DATA[43] ^ FAS_DATA[51] ^ FAS_DATA[59];
         B1_CALC_VALUE[2]        <= FAS_DATA[2] ^ FAS_DATA[10] ^ FAS_DATA[18] ^ FAS_DATA[26] ^ FAS_DATA[34] ^ FAS_DATA[42] ^ FAS_DATA[50] ^ FAS_DATA[58];
         B1_CALC_VALUE[1]        <= FAS_DATA[1] ^ FAS_DATA[9]  ^ FAS_DATA[17] ^ FAS_DATA[25] ^ FAS_DATA[33] ^ FAS_DATA[41] ^ FAS_DATA[49] ^ FAS_DATA[57];
         B1_CALC_VALUE[0]        <= FAS_DATA[0] ^ FAS_DATA[8]  ^ FAS_DATA[16] ^ FAS_DATA[24] ^ FAS_DATA[32] ^ FAS_DATA[40] ^ FAS_DATA[48] ^ FAS_DATA[56];
      end
      else begin
         B1_CALC_VALUE[7]        <= B1_CALC_VALUE[7] ^ FAS_DATA[7] ^ FAS_DATA[15] ^ FAS_DATA[23] ^ FAS_DATA[31] ^ FAS_DATA[39] ^ FAS_DATA[47] ^ FAS_DATA[55] ^ FAS_DATA[63];
         B1_CALC_VALUE[6]        <= B1_CALC_VALUE[6] ^ FAS_DATA[6] ^ FAS_DATA[14] ^ FAS_DATA[22] ^ FAS_DATA[30] ^ FAS_DATA[38] ^ FAS_DATA[46] ^ FAS_DATA[54] ^ FAS_DATA[62];
         B1_CALC_VALUE[5]        <= B1_CALC_VALUE[5] ^ FAS_DATA[5] ^ FAS_DATA[13] ^ FAS_DATA[21] ^ FAS_DATA[29] ^ FAS_DATA[37] ^ FAS_DATA[45] ^ FAS_DATA[53] ^ FAS_DATA[61];
         B1_CALC_VALUE[4]        <= B1_CALC_VALUE[4] ^ FAS_DATA[4] ^ FAS_DATA[12] ^ FAS_DATA[20] ^ FAS_DATA[28] ^ FAS_DATA[36] ^ FAS_DATA[44] ^ FAS_DATA[52] ^ FAS_DATA[60];
         B1_CALC_VALUE[3]        <= B1_CALC_VALUE[3] ^ FAS_DATA[3] ^ FAS_DATA[11] ^ FAS_DATA[19] ^ FAS_DATA[27] ^ FAS_DATA[35] ^ FAS_DATA[43] ^ FAS_DATA[51] ^ FAS_DATA[59];
         B1_CALC_VALUE[2]        <= B1_CALC_VALUE[2] ^ FAS_DATA[2] ^ FAS_DATA[10] ^ FAS_DATA[18] ^ FAS_DATA[26] ^ FAS_DATA[34] ^ FAS_DATA[42] ^ FAS_DATA[50] ^ FAS_DATA[58];
         B1_CALC_VALUE[1]        <= B1_CALC_VALUE[1] ^ FAS_DATA[1] ^ FAS_DATA[9]  ^ FAS_DATA[17] ^ FAS_DATA[25] ^ FAS_DATA[33] ^ FAS_DATA[41] ^ FAS_DATA[49] ^ FAS_DATA[57];
         B1_CALC_VALUE[0]        <= B1_CALC_VALUE[0] ^ FAS_DATA[0] ^ FAS_DATA[8]  ^ FAS_DATA[16] ^ FAS_DATA[24] ^ FAS_DATA[32] ^ FAS_DATA[40] ^ FAS_DATA[48] ^ FAS_DATA[56];
      end
   end
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      B1_FIANL_VALUE[7:0]        <= 8'd0;
   else begin
      if ( FAS_FCNT9[3:0]==4'd8 && FAS_FCNT270[8:0]==9'd269 &&  FAS_FCNT8[2:0]==3'd7) begin
         B1_FIANL_VALUE[7]       <= B1_CALC_VALUE[7] ^ FAS_DATA[7] ^ FAS_DATA[15] ^ FAS_DATA[23] ^ FAS_DATA[31] ^ FAS_DATA[39] ^ FAS_DATA[47] ^ FAS_DATA[55] ^ FAS_DATA[63];
         B1_FIANL_VALUE[6]       <= B1_CALC_VALUE[6] ^ FAS_DATA[6] ^ FAS_DATA[14] ^ FAS_DATA[22] ^ FAS_DATA[30] ^ FAS_DATA[38] ^ FAS_DATA[46] ^ FAS_DATA[54] ^ FAS_DATA[62];
         B1_FIANL_VALUE[5]       <= B1_CALC_VALUE[5] ^ FAS_DATA[5] ^ FAS_DATA[13] ^ FAS_DATA[21] ^ FAS_DATA[29] ^ FAS_DATA[37] ^ FAS_DATA[45] ^ FAS_DATA[53] ^ FAS_DATA[61];
         B1_FIANL_VALUE[4]       <= B1_CALC_VALUE[4] ^ FAS_DATA[4] ^ FAS_DATA[12] ^ FAS_DATA[20] ^ FAS_DATA[28] ^ FAS_DATA[36] ^ FAS_DATA[44] ^ FAS_DATA[52] ^ FAS_DATA[60];
         B1_FIANL_VALUE[3]       <= B1_CALC_VALUE[3] ^ FAS_DATA[3] ^ FAS_DATA[11] ^ FAS_DATA[19] ^ FAS_DATA[27] ^ FAS_DATA[35] ^ FAS_DATA[43] ^ FAS_DATA[51] ^ FAS_DATA[59];
         B1_FIANL_VALUE[2]       <= B1_CALC_VALUE[2] ^ FAS_DATA[2] ^ FAS_DATA[10] ^ FAS_DATA[18] ^ FAS_DATA[26] ^ FAS_DATA[34] ^ FAS_DATA[42] ^ FAS_DATA[50] ^ FAS_DATA[58];
         B1_FIANL_VALUE[1]       <= B1_CALC_VALUE[1] ^ FAS_DATA[1] ^ FAS_DATA[9]  ^ FAS_DATA[17] ^ FAS_DATA[25] ^ FAS_DATA[33] ^ FAS_DATA[41] ^ FAS_DATA[49] ^ FAS_DATA[57];
         B1_FIANL_VALUE[0]       <= B1_CALC_VALUE[0] ^ FAS_DATA[0] ^ FAS_DATA[8]  ^ FAS_DATA[16] ^ FAS_DATA[24] ^ FAS_DATA[32] ^ FAS_DATA[40] ^ FAS_DATA[48] ^ FAS_DATA[56];
      end
   end
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      B1_FIANL_VALUE_ME1[7:0]         <= 8'd0;
   else
      B1_FIANL_VALUE_ME1[7:0]         <= B1_FIANL_VALUE[7:0];
end


// B1 calculate
  assign  B1_XOR_VALUE[7:0]  =B1_FIANL_VALUE_ME1[7:0]  ^ DSCRM_DATA[63:56];
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      B1_ERROR_CNT[3:0]         <= 4'd0;
   else begin
      if ( DSCRM_FCNT9[3:0]==4'd1 && DSCRM_FCNT270[8:0]==9'd0 &&  DSCRM_FCNT8[2:0]==3'd0)
         B1_ERROR_CNT[3:0]      <= {3'd0, B1_XOR_VALUE[0]} + {3'd0, B1_XOR_VALUE[1]} + {3'd0, B1_XOR_VALUE[2]} + {3'd0, B1_XOR_VALUE[3]} + {3'd0, B1_XOR_VALUE[4]} + {3'd0, B1_XOR_VALUE[5]} + {3'd0, B1_XOR_VALUE[6]} + {3'd0, B1_XOR_VALUE[7]};
   end
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      MPI_PER_B1COUNT[3:0]          <= 4'd0;
   else begin
      if ( DSCRM_FCNT9[3:0]==4'd8 && DSCRM_FCNT270[8:0]==9'd269 &&  DSCRM_FCNT8[2:0]==3'd7) begin
         MPI_PER_B1COUNT[3:0]       <= B1_ERROR_CNT[3:0];
      end
   end
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      MPI_PER_B1PULSE               <= 1'b0;
   else begin
      if ( DSCRM_FCNT9[3:0]==4'd8 && DSCRM_FCNT270[8:0]==9'd269 &&  DSCRM_FCNT8[2:0]==3'd7 && B1_ERROR_CNT[3:0]!=4'd0)
         MPI_PER_B1PULSE            <= 1'b1;
      else if ( DSCRM_FCNT9[3:0]==4'd0 && DSCRM_FCNT270[8:0]==9'd0 &&  DSCRM_FCNT8[2:0]==3'd7)
         MPI_PER_B1PULSE            <= 1'b0;
   end
end

endmodule
